package com.zhima.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhima.entity.OjQuestionBank;
import com.zhima.entity.OjQuestionBindBank;
import com.zhima.exception.ZhimaOjException;
import com.zhima.mapper.OjQuestionBindBankMapper;
import com.zhima.service.OjQuestionBankService;
import com.zhima.service.OjQuestionBindBankService;
import com.zhima.service.OjQuestionPublishService;
import com.zhima.util.AuthorizationUtil;
import com.zhima.vo.QuestionBankContestEditQuestionVO;
import com.zhima.vo.QuestionTableVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;

import static com.zhima.constant.QuestionBankRedisConstant.QUESTION_REFER;
import static com.zhima.exception.ErrorCode.NOT_ALLOW_DUPLICATE_QUESTION;
import static com.zhima.exception.ErrorCode.NOT_FIND_QUESTION_BY_QUESTION_NUMBER;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zhima
 * @since 2023-08-25
 */
@Service
public class OjQuestionBindBankServiceImpl extends ServiceImpl<OjQuestionBindBankMapper, OjQuestionBindBank> implements OjQuestionBindBankService {
    @Autowired
    private OjQuestionBindBankMapper ojQuestionBindBankMapper;
    @Autowired
    private OjQuestionBankService ojQuestionBankService;
    @Autowired
    private OjQuestionPublishService ojQuestionPublishService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public List<QuestionTableVO> queryQuestionsByQuestionBankId(Long questionBankId) {
        return ojQuestionBindBankMapper.queryQuestionsByQuestionBankId(questionBankId);
    }

    @Override
    public boolean bindQuestionToBank(Long userId, OjQuestionBindBank questionBindBank) {
        AuthorizationUtil.isLoginUserResource(userId, ojQuestionBankService.getById(questionBindBank.getQuestionBankId()).getUploaderId());
        if (lambdaQuery().eq(OjQuestionBindBank::getQuestionBankId, questionBindBank.getQuestionBankId()).eq(OjQuestionBindBank::getQuestionNumber, questionBindBank.getQuestionNumber()).count() > 0) {
            throw new ZhimaOjException(NOT_ALLOW_DUPLICATE_QUESTION);
        }
        Long questionId = ojQuestionPublishService.getQuestionIdByQuestionNumber(questionBindBank.getQuestionNumber());
        // 没有此题目
        if (questionId == null) {
            throw new ZhimaOjException(NOT_FIND_QUESTION_BY_QUESTION_NUMBER);
        }
        // 题单题目数量增1
        ojQuestionBankService.updateQuestionNum(questionBindBank.getQuestionBankId(), true);
        questionBindBank.setQuestionId(questionId);
        // 增加引用
        stringRedisTemplate.opsForSet().add(QUESTION_REFER + questionId, questionBindBank.getQuestionBankId().toString());
        // 保存
        return save(questionBindBank);
    }

    @Override
    public List<QuestionBankContestEditQuestionVO> queryQuestionBankSimpleQuestion(Long questionBankId) {
        return ojQuestionBindBankMapper.queryQuestionBankSimpleQuestion(questionBankId);
    }

    @Override
    public boolean changeQuestionIndex(Long questionBankId, String[] afterSequence) {
        boolean success = true;
        for (int i = 0; i < afterSequence.length; i++) {
            success &= ojQuestionBindBankMapper.changeQuestionIndex(questionBankId, afterSequence[i], i);
        }
        return success;
    }

    @Override
    public boolean unbindQuestionToBank(Long userId, Long questionBankId, Integer questionIndex) {
        OjQuestionBank questionBank = ojQuestionBankService.getById(questionBankId);
        AuthorizationUtil.isLoginUserResource(userId, questionBank.getUploaderId());
        // 减少题单题目数量
        ojQuestionBankService.updateQuestionNum(questionBank.getId(), false);
        // 删除题目绑定
        lambdaUpdate().eq(OjQuestionBindBank::getQuestionBankId, questionBankId).eq(OjQuestionBindBank::getQuestionIndex, questionIndex).remove();
        // 已经没有题目了，不需要更新索引
        if (questionBank.getQuestionNum() == 1) {
            return true;
        }
        // 更新题目索引
        // questionBindBank.getQuestionIndex()后的题目索引都要减1
        return ojQuestionBindBankMapper.decreaseQuestionIndex(questionBank.getId(), questionIndex);
    }
}
